﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Deployment.Application;
using System.Windows.Forms;
using System.ComponentModel;


public class clsUpdateApp
{
    ApplicationDeployment ad;

    #region InstallSync
    public string GetUltimaVersion()
    {
        UpdateCheckInfo info = null;

        if (ApplicationDeployment.IsNetworkDeployed)
        {
            ad = ApplicationDeployment.CurrentDeployment;

            try
            {
                info = ad.CheckForDetailedUpdate();

                return info.AvailableVersion.ToString();
            }
            catch
            { return "Desconocida"; }
        }

        return "No NetworkDeployed";
    }

    public void InstallUpdateSyncWithInfo()
    {
        UpdateCheckInfo info = null;

        if (ApplicationDeployment.IsNetworkDeployed)
        {
            ad = ApplicationDeployment.CurrentDeployment;

            try
            {
                info = ad.CheckForDetailedUpdate();

            }
            catch (DeploymentDownloadException dde)
            {
                MessageBox.Show("La nueva versión de la aplicación no se puede descargar en este momento. \n \nPor favor, compruebe la conexión de red, o inténtelo de nuevo más tarde. Error: " + dde.Message);
                return;
            }
            catch (InvalidDeploymentException ide)
            {
                MessageBox.Show("No se puede comprobar si hay una nueva versión de la aplicación. La implementación de ClickOnce está dañado. Por favor, vuelva a implementar la aplicación y vuelva a intentarlo. Error: " + ide.Message);
                return;
            }
            catch (InvalidOperationException ioe)
            {
                MessageBox.Show("Esta aplicación no se puede actualizar. Probablemente no es una aplicación ClickOnce. Error: " + ioe.Message);
                return;
            }

            if (info.UpdateAvailable)
            {
                Boolean doUpdate = true;

                if (!info.IsUpdateRequired)
                {
                    DialogResult dr = MessageBox.Show("Hay disponible una actualización (" + info.AvailableVersion +
                        "). ¿Desea actualizar la aplicación ahora?", "Actualización disponible", MessageBoxButtons.OKCancel);
                    if (!(DialogResult.OK == dr))
                    {
                        doUpdate = false;
                    }
                }
                else
                {
                    // Display a message that the app MUST reboot. Display the minimum required version.
                    MessageBox.Show("Esta aplicación ha detectado una actualización obligatoria de su actual " +
                        "una versión a otra " + info.MinimumRequiredVersion.ToString() +
                        "La aplicación se instala la actualización y reiniciar.",
                        "Actualización disponible", MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                }

                if (doUpdate)
                {
                    try
                    {
                        ad.Update();
                        MessageBox.Show("La aplicación se ha actualizado y necesita reiniciar.");
                        Application.Restart();
                    }
                    catch (DeploymentDownloadException dde)
                    {
                        MessageBox.Show("No se puede instalar la última versión de la aplicación.\n\nPor favor, compruebe la conexión de red, o inténtelo de nuevo más tarde. Error: " + dde);
                        return;
                    }
                }
            }
        }
    }
    #endregion

    #region InstallASync
    long sizeOfUpdate = 0;

    Label downloadStatus;

    Form _Form;

    bool _bolProcesoCancelado;

    bool _bolForzar;

    public void InstallUpdateAsyncWithInfo(bool bolForzar)
    {
        _bolForzar = bolForzar;

        InstallUpdateAsyncWithInfo(ref downloadStatus, ref _Form);
    }

    public void InstallUpdateAsyncWithInfo(ref Label TextBoxdownloadStatus, ref Form oForm)
    {
        downloadStatus = TextBoxdownloadStatus;

        _Form = oForm;

        if (ApplicationDeployment.IsNetworkDeployed)
        {
            _bolProcesoCancelado = false;

            ad = ApplicationDeployment.CurrentDeployment;

            ad.CheckForUpdateCompleted += new CheckForUpdateCompletedEventHandler(ad_CheckForUpdateCompleted);

            ad.CheckForUpdateProgressChanged += new DeploymentProgressChangedEventHandler(ad_CheckForUpdateProgressChanged);

            ad.CheckForUpdateAsync();
        }
    }

    void ad_CheckForUpdateProgressChanged(object sender, DeploymentProgressChangedEventArgs e)
    {
        if (downloadStatus != null) downloadStatus.Text = String.Format("Downloading: {0}. {1:D}K of {2:D}K downloaded.", GetProgressString(e.State), e.BytesCompleted / 1024, e.BytesTotal / 1024);
    }

    string GetProgressString(DeploymentProgressState state)
    {
        if (state == DeploymentProgressState.DownloadingApplicationFiles)
        {
            return "application files";
        }
        else if (state == DeploymentProgressState.DownloadingApplicationInformation)
        {
            return "application manifest";
        }
        else
        {
            return "deployment manifest";
        }
    }

    void ad_CheckForUpdateCompleted(object sender, CheckForUpdateCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            MessageBox.Show("ERROR: No se pudo recuperar la nueva versión de la aplicación. Motivo: \n" + e.Error.Message + "\nComunique este error al administrador del sistema.");
            return;
        }
        else if (e.Cancelled == true)
        {
            MessageBox.Show("La actualización fue cancelada.");
        }

        // Ask the user if they would like to update the application now. 
        if (e.UpdateAvailable && !_bolProcesoCancelado)
        {
            sizeOfUpdate = e.UpdateSizeBytes;

            if (!e.IsUpdateRequired)
            {

                if (_bolForzar ||
                    (MessageBox.Show("Hay disponible una actualización. ¿Desea actualizar la aplicación ahora?",
                    "Actualización disponible", MessageBoxButtons.OKCancel) == DialogResult.OK))
                {
                    BeginUpdate();
                }
                else
                {
                    ad.UpdateAsyncCancel();

                    _bolProcesoCancelado = true;

                    if (_Form != null) _Form.Close();
                }
            }
            else
            {
                MessageBox.Show("Una actualización obligatoria está disponible para su aplicación. Vamos a instalar la actualización ahora, después de lo cual vamos a guardar todos sus datos en progreso y reiniciar la aplicación.");
                BeginUpdate();
            }
        }
    }

    private void BeginUpdate()
    {
        ad = ApplicationDeployment.CurrentDeployment;

        ad.UpdateCompleted += new AsyncCompletedEventHandler(ad_UpdateCompleted);

        // Indicate progress in the application's status bar.
        ad.UpdateProgressChanged += new DeploymentProgressChangedEventHandler(ad_UpdateProgressChanged);

        ad.UpdateAsync();
    }

    void ad_UpdateProgressChanged(object sender, DeploymentProgressChangedEventArgs e)
    {
        String progressText = String.Format("{0:D}K out of {1:D}K downloaded - {2:D}% complete", e.BytesCompleted / 1024, e.BytesTotal / 1024, e.ProgressPercentage);

        if (downloadStatus != null) downloadStatus.Text = progressText;
    }

    void ad_UpdateCompleted(object sender, AsyncCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            MessageBox.Show("La actualización de la última versión de la aplicación se ha cancelado.");
            return;
        }
        else if (e.Error != null)
        {
            MessageBox.Show("ERROR: No se pudo instalar la última versión de la aplicación. Motivo: \n" + e.Error.Message + "\nComunique este error al administrador del sistema.");
            return;
        }

        DialogResult dr = MessageBox.Show("La aplicación se ha actualizado. Reiniciar ahora? (Si no reinicia ahora, la nueva versión no entrará en vigor hasta después de cerrar e iniciar la aplicación de nuevo.) ", "Reiniciar Aplicación", MessageBoxButtons.OKCancel);
        if (dr == DialogResult.OK)
        {
            Application.Restart();
        }
    }
    #endregion

}

